/*
 * Copyright (c) 2006-2022, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 */

#include <rtthread.h>
#include <dfs_romfs.h>
#include <dfs_fs.h>

#define DRV_DEBUG
#define LOG_TAG             "init.fs"
#include <drv_log.h>

#define EMMC_DEVICE_NAME "emmc"

static const struct romfs_dirent rootfs_dirent[] =
{
    {ROMFS_DIRENT_DIR, "mnt", RT_NULL, 0},
    {ROMFS_DIRENT_DIR, "usr", RT_NULL, 0},
    {ROMFS_DIRENT_DIR, "var", RT_NULL, 0},
};

static const struct romfs_dirent rootfs =
{
    ROMFS_DIRENT_DIR, "/", (rt_uint8_t *)rootfs_dirent, sizeof(rootfs_dirent) / sizeof(rootfs_dirent[0])
};

static struct rt_semaphore fs_sem;
static rt_bool_t fs_ready = RT_FALSE;

int mount_rootfs()
{
    // mount ROMFS as /
    int retval = dfs_mount(RT_NULL, "/", "rom", 0, (const void *)&rootfs);
    if (retval != 0)
    {
        LOG_E("%s: mount romfs FAILED, %d!", __func__, retval);
        return -1;
    }
    LOG_I("%s: mount romfs to / OK!", __func__);

    rt_err_t err = rt_sem_init(&fs_sem, "fs_sem", 0, RT_IPC_FLAG_FIFO);
    if (err != RT_EOK) {
        LOG_E("%s: rt_sem_init FAILED, %d!", __func__, err);
        return -1;
    }

    // mount eMMC as /mnt
    retval = dfs_mount(EMMC_DEVICE_NAME, "/mnt", "elm", 0, RT_NULL);
    if (retval != 0) {
        LOG_E("%s: mount %s to /mnt FAILED, %d!", __func__, EMMC_DEVICE_NAME, retval);
        return -1;
    }
    LOG_I("%s: mount %s to /mnt OK!", __func__, EMMC_DEVICE_NAME);

    err = rt_sem_release(&fs_sem);
    if (err != RT_EOK) {
        LOG_E("%s: rt_sem_release FAILED, %d!", __func__, err);
        return -1;
    }
    fs_ready = RT_TRUE;
    return 0;
}
INIT_APP_EXPORT(mount_rootfs);

void fs_wait_ready()
{
    if (fs_ready) {
        return;
    }

    LOG_I("%s: wait fs ready ...", __func__);
    rt_err_t err = rt_sem_take(&fs_sem, RT_WAITING_FOREVER);
    if (err != RT_EOK) {
        LOG_E("%s: rt_sem_take FAILED, %d!", __func__, err);
        return;
    }
    LOG_I("%s: wait fs ready DONE!", __func__);
}
